import { Context } from 'koa'
import { getListSer, addSer, putSer, getDetailSer, delSer,addSerArr } from '@/business/service'
import { userType} from '@/types'
import {  IjiaoyantableQueryType, IjiaoyantableQuerySerType, Ijiaoyantable, IjiaoyantableSer } from '@/types/equipment/jiaoyantable'
import errors from '@/app/err.type'
import { formatHumpLineTransfer } from '@/business/utils'
import { excelJsExportJiaoYanJieGuo } from '@/business/utils/excel'
import {  excelBaseStyle } from '@/business/public/excelMap'
import JiaoyanjieguoTable from '@/mysql/model/equipment/jiaoyantable.model'
import { Op } from 'sequelize'
import fs from 'fs';
import { updatePassword, getAllUserInfoSer } from '@/business/service/user.service';
import { generateFileId, parseFiles, checkFiles, mockStandrdData } from '@/business/utils/format';
import os from 'os'
import path from 'path'
import { queryConditionsDataFn } from './jiaoyanguize.middleware';
import { shebeiqueryConditionsDataFn } from './shebei.middleware';

const { uploadParamsErr, getListErr, sqlErr, delErr, exportExcelErr} = errors


// 获取列表
export const getListMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const { pageNum, pageSize, ...params } = ctx.query as unknown as IjiaoyantableQueryType
    let {groupName} = ctx.query
    let shebeiRes = []
    if (groupName) {
      shebeiRes = await shebeiqueryConditionsDataFn({groupName})
    }
    let deviceNameArr = shebeiRes.map(item => item.device_name)
    const newParams = { pageNum, pageSize } as IjiaoyantableQuerySerType
    if(params.originalFilename) newParams.original_filename = { [Op.like]: `${params.originalFilename  }%` }
    if(params.deptId) newParams.dept_id = { [Op.eq]: params.deptId  }
    if (groupName) {
      newParams.original_filename = { [Op.in]: deviceNameArr }
    }
    if (params.createTimeDuration) {
      let [start,end] = params.createTimeDuration.split(',')
      newParams.created_at ={
        [Op.gt]: new Date(start),
        [Op.lt]: new Date(end),
      }
    }
    const res = await getListSer<IjiaoyantableQuerySerType>(JiaoyanjieguoTable, newParams);



    ctx.state.formatData = res
    await next()
  } catch (error) {
    console.error('查询列表失败', error)
    return ctx.app.emit('error', getListErr, ctx)
  }
}

// 新增
export const getAddMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const { userName } = ctx.state.user as userType
    const addContent = ctx.request.body as Ijiaoyantable
    const addContent2 = { ...addContent, createBy: userName }
    const newAddContent = formatHumpLineTransfer(addContent2, 'line') as  IjiaoyantableSer

    await addSer<IjiaoyantableSer>(JiaoyanjieguoTable, newAddContent)
    await next()
  } catch (error) {
    console.error('新增失败', error)
    return ctx.app.emit('error', uploadParamsErr, ctx)
  }
}
// 批量新增
export const getAddBatchMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const { userName,userId } = ctx.state.user as userType
    const { password, ...userRes } = await getAllUserInfoSer({ userId });
    const finRes = { ...userRes };
    const {dept_id} = finRes    
    const addContent = ctx.request.body as any
    addContent.forEach((item:any) => {
      item.dept_id = dept_id
      item.create_by = userName
    })
    await addSerArr(JiaoyanjieguoTable, addContent)
    await next()
  } catch (error) {
    console.error('同步失败', error)
    return ctx.app.emit('error', uploadParamsErr, ctx)
  }
}

// 删除
export const delMid = async (ctx: Context, next: () => Promise<void>) => {
  try {

    await delSer(JiaoyanjieguoTable, { table_id: ctx.state.ids })
  } catch (error) {
    console.error('删除失败', error)
    return ctx.app.emit('error', delErr, ctx)
  }

  await next()
}

// 获取详细数据
export const getDetailMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const res = await getDetailSer<IjiaoyantableSer>(JiaoyanjieguoTable, { table_id: ctx.state.ids  })

    ctx.state.formatData = res
  } catch (error) {
    console.error('详细数据查询错误', error)
    return ctx.app.emit('error', sqlErr, ctx)
  }

  await next()
}

// 修改
export const putMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const { userName } = ctx.state.user as userType
    const res = ctx.request.body as Ijiaoyantable
    const lineData =  formatHumpLineTransfer(res, 'line') as IjiaoyantableSer
    const { table_id} = lineData

    await putSer<IjiaoyantableSer>(JiaoyanjieguoTable, { table_id }, { ...lineData, update_by: userName})

    await next()
  } catch (error) {
    console.error('修改失败', error)
    return ctx.app.emit('error', uploadParamsErr, ctx)
  }
}

// 导出
export const exportMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    const list = ctx.state.formatData
    const {dicts} = ctx.state
    list.forEach((item:any,index) => {
      item.index = index + 1
      let jiaoyanjieguo = JSON.parse(item.jiaoyanjieguo)
      let tableData:any = {}
      // 控制列宽
      let padEndMap:any = {
        0:'50',
        1:'10',
        2:'10',
        3:'10',
        4:'50',
      }
      tableData.headers = ['参数',	'值',	'期望值',	'校验',	'站长备注']
      // tableData.headers = ['a',	'b',	'c',	'd',	'e']
      tableData.rows = jiaoyanjieguo.checkData.map((item:any) => {
        return [item.key,	item.value,	item.expected,item.status== '0' ? '通过':'不通过',	item.check_remark]
      })
      // tableData.rows.unshift(tableData.headers)
      let tableHeaderText = tableData.headers.map((item,index) => {
        // 一个汉字占两个字母的宽度，所以要减一些
        return item.padEnd(padEndMap[index] - item.length)
      }).join('')+ `\n`
      let tableText = tableData.rows.map(row => {
        return row.map((cell,index) => {
          if (!cell) {
            cell = ''
          }
          cell = cell.toString()
          return cell.padEnd(padEndMap[index])
        }).join('')
      }).join('\n');
      item.jiaoyanjieguo = tableHeaderText + tableText
    })
    let headerColumns = [
      {title:"序号",dataIndex:"index",width:100},
      {title:"名称",dataIndex:"original_filename",width:300},
      {title:"创建时间",dataIndex:"created_at",width:300},
      {title:"校验结果",dataIndex:"jiaoyanjieguo",width:900},
      {title:"审核结果",dataIndex:"check_result",width:300},
      {title:"审核人",dataIndex:"check_user_id",width:300}
    ]
    // 序号	名称	创建时间	校验结果	校验结果详情	审核结果	审核人
    excelBaseStyle.alignment.horizontal = 'left'
    // 表格数据
    const buffer = await excelJsExportJiaoYanJieGuo({
      sheetName: '文件校验结果表',
      style: excelBaseStyle,
      headerColumns,
      tableData: list,
      dicts
    })
    ctx.state.buffer = buffer
    await next()
  } catch (error) {
    console.error('导出失败', error)
    return ctx.app.emit('error', exportExcelErr, ctx)
  }
}

// 上传ini文件
export const uploadIniMid = async (ctx: Context, next: () => Promise<void>) => {
  const { files } = (ctx.request as any);
  // iniFiles是前端传的参数
  const fileArr = []
  if (!Array.isArray(files.iniFiles)) {
    fileArr.push(files.iniFiles)
  } else {
    fileArr.push(...files.iniFiles)
  }
  const { work_type,file_type = '' } = (ctx.request as any).body;
  // 查询校验规则
  let deviceNameArr = fileArr.map((file:any) => {
    return file.originalFilename
  })
  const guizeRes = await queryConditionsDataFn({work_type,deviceNameArr});
  let epmtyRuleDeviceArr = []
  fileArr.forEach((file:any) => {
    let deviceRuleArr = guizeRes.filter((item:any) => item.device_name === file.originalFilename)
    if (deviceRuleArr.length === 0) {
      epmtyRuleDeviceArr.push(file.originalFilename)
    }
  })
  if (epmtyRuleDeviceArr.length > 0) {
    return ctx.app.emit('error', {code:'400',message:`上传文件中，${epmtyRuleDeviceArr.join(',')}没有对应校验规则，请到【设备管理】增加设备和校验规则`}, ctx)
  }
  // const guizeMap = guizeRes.reduce((cur,total) => {
  //   const { key, min, max, equal, need_check } = cur;
  //   total[key] = equal
  // },{})
  // 找出用户id 关联的 部门id
  const { userId } = ctx.state.user as userType;
  const { password, ...userRes } = await getAllUserInfoSer({ userId });
  const finRes = { ...userRes };
  const {dept_id} = finRes
  const addItems = [
  ]
  await Promise.all(fileArr.map((file: any) => new Promise<void>((resolve,reject) =>{
      fs.readFile(file.filepath, 'utf-8', (err, data) => {
        if (err) {
          console.log("读取文件失败-----")
          reject()
        }
        const fileName = file.originalFilename;
        // 解析文件内容
        const keyValuePairs = parseFiles(data, fileName);
        // 校验
        const jiaoyanjieguo = checkFiles(guizeRes.filter((item:any) => item.device_name === file.originalFilename), keyValuePairs);
        const {checkData,checkStatus} = jiaoyanjieguo;
        const check_result_status= checkStatus === '0' ? '1': '0';
/* 
check_result
          '0':'待审核',
          '1':'自动审核通过',
          '2':'省长审核通过',
          '3':'省长审核不通过',
*/        
        addItems.push({
          filepath: file.filepath,
          original_filename: file.originalFilename,
          new_filename: 'fileId',
          jiaoyanjieguo: JSON.stringify(jiaoyanjieguo),
          check_result:  check_result_status, // 审核结果状态
          dept_id
        })
        resolve()
      }); 
    }))).then(async () => {

    // 入库
    const res = await addSerArr(JiaoyanjieguoTable, addItems)
    
  })
  await next();
};


// 获取列表查询条件
export const getListParamMid = async (ctx: Context, next: () => Promise<void>) => {
  try {
    let params:any =  {}
    if (ctx.request.body) {
      params = JSON.parse(Object.keys(ctx.request.body)[0])
    }
    let {groupName} = params
    let shebeiRes = []
    if (groupName) {
      shebeiRes = await shebeiqueryConditionsDataFn({groupName})
    }
    let deviceNameArr = shebeiRes.map(item => item.device_name)
    const newParams = {  } as IjiaoyantableQuerySerType
    if(params.originalFilename) newParams.original_filename = { [Op.like]: `${params.originalFilename  }%` }
    if(params.deptId) newParams.dept_id = { [Op.eq]: params.deptId  }
    if (groupName) {
      newParams.original_filename = { [Op.in]: deviceNameArr }
    }
    ctx.state.queryParam = newParams
    await next()
  } catch (error) {
    console.error('查询列表失败', error)
    return ctx.app.emit('error', getListErr, ctx)
  }
}